from typing import Callable, Dict, Optional
from nicegui.awaitable_response import AwaitableResponse
from nicegui import ui, app
from nicegui.element import Element
from pathlib import Path

_ROOT_DIR = Path(__file__).parent
_STATIC_DIR = _ROOT_DIR / "static"
_STATIC_URL_PATH = "/lk_sheet_98c23af5945a"


@app.on_startup
def on_server_startup():
    app.add_static_files(_STATIC_URL_PATH, _STATIC_DIR)

    folders = (path for path in _STATIC_DIR.rglob("*") if path.is_dir())
    for folder in folders:
        rel_path = (
            _STATIC_URL_PATH
            + "/"
            + str(folder.relative_to(_STATIC_DIR)).replace("\\", "/")
        )
        app.add_static_files(rel_path, folder)


class Luckysheet(
    Element,
    component="luckysheet_vue.js",
):
    def __init__(self, options: Dict, hook: Dict[str, Callable]) -> None:
        """

        Args:
            options (Dict): [goto docs](https://mengshukeji.gitee.io/LuckysheetDocs/zh/guide/config.html#%E5%9F%BA%E7%A1%80%E7%BB%93%E6%9E%84)
            hook (Dict[str, Callable]): [goto docs](https://mengshukeji.gitee.io/LuckysheetDocs/zh/guide/config.html#%E9%92%A9%E5%AD%90%E5%87%BD%E6%95%B0)


        ## Examples

        """
        super().__init__()

        self._props["contarnerId"] = f"c{self.id}"
        self._props["options"] = options

        hook_callback = {key: id(v) for key, v in hook.items()}
        self._props["hookMapping"] = hook_callback

        self.__hook_callback_map: Dict[int, Callable] = {
            id(fn): fn for fn in hook.values()
        }

        def onHook(e):
            fn = self.__hook_callback_map[e.args["hookId"]]
            fn(e.args["args"])

        self.on("onHook", onHook)

        # TODO:应该保证一个页面只执行一次
        Luckysheet.__setup_static_assets()

    @staticmethod
    def __setup_static_assets():
        ui.add_head_html(
            f"""<link rel='stylesheet' href='{_STATIC_URL_PATH}/plugins/css/pluginsCss.css' />
                        <link rel='stylesheet' href='{_STATIC_URL_PATH}/plugins/plugins.css' />
                        <link rel='stylesheet' href='{_STATIC_URL_PATH}/css/luckysheet.css' />
                        <link rel='stylesheet' href='{_STATIC_URL_PATH}/assets/iconfont/iconfont.css' />"""
        )
        ui.add_body_html(
            f"""<script src="{_STATIC_URL_PATH}/plugins/js/plugin.js"></script>
                <script src="{_STATIC_URL_PATH}/luckysheet.umd.js"></script>"""
        )

    def run_api(
        self, name: str, *args, timeout: float = 1, check_interval: float = 0.01
    ) -> AwaitableResponse:
        """call luckysheet api

        [goto docs](https://mengshukeji.gitee.io/LuckysheetDocs/zh/guide/api.html#api)

        Args:
            name (str): api name. [goto docs](https://mengshukeji.gitee.io/LuckysheetDocs/zh/guide/api.html#api)
            timeout (float, optional): _description_. Defaults to 1.
            check_interval (float, optional): _description_. Defaults to 0.01.

        Returns:
            AwaitableResponse: _description_
        """
        return self.run_method(
            "runApi", name, *args, timeout=timeout, check_interval=check_interval
        )
